package com.hefan.api.controller.live;

import java.sql.Timestamp;
import java.util.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import com.alibaba.dubbo.rpc.RpcContext;
import com.cat.common.entity.ResultBean;
import com.hefan.api.service.live.*;
import com.hefan.api.util.DateTimeUtils;
import com.hefan.common.util.*;
import com.hefan.common.util.HttpUtils;
import com.hefan.live.bean.*;
import com.hefan.live.itf.LivingRedisOptService;
import com.hefan.live.itf.RoomEnterExitOptService;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.cat.common.entity.Page;
import com.cat.common.entity.ResultPojo;
import com.cat.common.meta.ResultCode;
import com.cat.tiger.util.GlobalConstants;
import com.hefan.api.service.UserLocalService;
import com.hefan.common.ons.TopicRegistry;
import com.hefan.common.ons.bean.Message;
import com.hefan.common.ons.service.ONSProducer;
import com.hefan.user.bean.WebUser;

@Controller
@RequestMapping("/v1/live")
public class LiveController {
    public  Logger logger = LoggerFactory.getLogger(LiveController.class);

	@Resource
	LiveLogLocalService liveLogLocalService;
	@Resource
	UserLocalService userLocalService;
	@Resource
	LiveRoomLocalService liveRoomLocalService;
	@Resource
	RoomOptLocalService roomOptLocalService;
	@Reference
	ONSProducer onsProducer;
	@Resource
	LiveNoticeLocalService liveNoticeLocalService;
	@Resource
	LiveImOptLocalService liveImOptLocalService;
	@Resource
	LivingLocalService livingLocalService;
	@Reference
	RoomEnterExitOptService roomEnterExitOptService;
    @Reference
    LivingRedisOptService livingRedisOptService;

	/**
	 * 获取开播Token
	 */
	@RequestMapping(value = "/getLiveToken", method = RequestMethod.GET)
	@ResponseBody
	public String getLiveToken(HttpServletRequest req) {
		try {
			LiveVo liveVo = HttpUtils.initParam(req, LiveVo.class);
			if (null == liveVo || StringUtils.isBlank(liveVo.getUserId())) {
				return JSON.toJSONString(new ResultPojo(ResultCode.ParamException));
			}
			String token = IdgenUtil.getUuid();
			if (StringUtils.isBlank( livingRedisOptService.getLiveToken(liveVo.getUserId()))) {
				livingRedisOptService.setLiveToken(liveVo.getUserId(), token);
			}
			token = livingRedisOptService.getLiveToken( liveVo.getUserId());
			//token 异常，需要前端重试
			if(StringUtils.isBlank(token)){
				return JSON.toJSONString(new ResultPojo(ResultCode.TOKEN_TRY_AGAIN));
			}
			Map mapParam = new HashMap();
			mapParam.put("liveToken", token);
			return JSON.toJSONString(new ResultBean(ResultCode.SUCCESS, mapParam));
		} catch (Exception e) {
			return JSON.toJSONString(new ResultPojo(ResultCode.UnknownException));
		}
	}

	/**
	 * 主播开启直播
	 */
	@ResponseBody
	@RequestMapping("/liveStart")
	public String liveStart(HttpServletRequest req) {
		try {
			LiveVo liveVo = HttpUtils.initParam(req, LiveVo.class);
			// 参数异常
			if (null == liveVo || StringUtils.isBlank(liveVo.getUserId()) || StringUtils.isBlank(liveVo.getLiveName())
					|| StringUtils.isBlank(liveVo.getDisplayGraph()) || StringUtils.isBlank(liveVo.getLiveImg())
					|| StringUtils.isBlank(liveVo.getToken())) {
				return JSON.toJSONString(new ResultPojo(ResultCode.ParamException));
			}
			WebUser user = userLocalService.getWebUserByUserId(liveVo.getUserId());
			//用户不存在
			if (null == user) {
				return JSON.toJSONString(new ResultPojo(ResultCode.LoginUserIsNotExist));
			}
			// 账户异常（冻结，删除）
			if (user.getState() == 1 || user.getSuperiorState() == 1 || user.getIsDel() == 1) {
				return JSON.toJSONString(new ResultPojo(ResultCode.LoginUserIsLock));
			}
			// 用户不是主播
			if (user.getUserType() != GlobalConstants.USER_TYPE_FAMOUS
					&& user.getUserType() != GlobalConstants.USER_TYPE_STAR
					&& user.getUserType() != GlobalConstants.USER_TYPE_SITE) {
				return JSON.toJSONString(new ResultPojo(ResultCode.UserIsNotAnchor));
			}

			//验证开播token
			String token = livingRedisOptService.getLiveToken(liveVo.getUserId());
			if (StringUtils.isBlank(token) || !token.equals(liveVo.getToken())) {
				return JSON.toJSONString(new ResultPojo(ResultCode.TOKEN_ERROR));
			}

			// 处理开播账号在其他直播间的问题
			List liveLogPersonsList = roomEnterExitOptService.enterLiveRoomCheck(liveVo.getUserId());
			if (liveLogPersonsList.size() > 0) {
				return JSON.toJSONString(new ResultPojo(ResultCode.LiveRoomRepeat, liveLogPersonsList));
			}
			LiveRoom findRoom = liveRoomLocalService.getLiveRoomByUserId(liveVo.getUserId());
			LiveLog liveLog = new LiveLog();
			LiveRoom liveRoom = new LiveRoom();
			Timestamp now_ = new Timestamp(new Date().getTime());
			Map<String, Object> dataMap = new HashMap<String, Object>();
			// 直播间信息不存在，参数有误
			if (null == findRoom) {
				return JSON.toJSONString(new ResultPojo(ResultCode.ParamException));
			}
			// 主播被禁播
			if (findRoom.getStuff() == GlobalConstants.AUTHOR_LOCK) {
				return JSON.toJSONString(new ResultPojo(ResultCode.LiveIsBanned));
			}
			// 主播正在直播
			if (findRoom.getStatus() == GlobalConstants.AUTHOR_LIVING) {
				return JSON.toJSONString(new ResultPojo(ResultCode.LiveIsLiveing));
			}

			//清理历史观众及机器人信息
			livingLocalService.endLiveClearNoAsync(liveVo.getUserId());

			// 直播开始进行初始化记录操作
			liveRoom.setUserId(liveVo.getUserId());
			liveRoom.setChatRoomId(findRoom.getChatRoomId());
			liveRoom.setStatus(GlobalConstants.AUTHOR_LIVING);
			liveRoom.setLiveName(liveVo.getLiveName());
			liveRoom.setLiveImg(liveVo.getLiveImg());
			liveRoom.setLocation(StringUtils.isBlank(liveVo.getLocation()) ? GlobalConstants.DEFAULT_LOCATION : liveVo.getLocation());
			liveRoom.setStartTime(now_);// 冗余最新直播时间，用于其他地方做排序
			liveRoom.setType(user.getUserType());//冗余主播的类型，用户热门排序

			liveLog.setUserId(liveVo.getUserId());
			liveLog.setChatRoomId(findRoom.getChatRoomId());
			liveLog.setLocation(StringUtils.isBlank(liveVo.getLocation()) ? GlobalConstants.DEFAULT_LOCATION : liveVo.getLocation());
			liveLog.setDisplayGraph(liveVo.getDisplayGraph());
			liveLog.setLiveName(liveVo.getLiveName());
			liveLog.setLiveImg(liveVo.getLiveImg());
			//新增字段
			liveLog.setIsVipLive(0);
			liveLog.setIsShow(1);
			liveLog.setIsLandscape(liveVo.getIsLandscape());

			//拼接推拉流地址
			String pushPre = DynamicProperties.getString("ali.push.domain.pre");
			String pushSuf = DynamicProperties.getString("ali.push.domain.suf");
			String pull = DynamicProperties.getString("ali.pull.domain");

            if (liveVo.getIsLandscape() == 0) {//竖屏
                liveLog.setLiveUuid(liveLog.getUserId() + "hefan" + DateTimeUtils.getYmdhms() + "_0");
            } else {//横屏
                liveLog.setLiveUuid(liveLog.getUserId() + "hefan" + DateTimeUtils.getYmdhms() + "_1");
            }
            liveRoom.setLiveUuid(liveLog.getLiveUuid());
			liveLog.setLiveUrl( pushPre + liveLog.getLiveUuid() + pushSuf);
			liveLog.setPullUrl( pull + liveLog.getLiveUuid());

			//多套推拉流地址
			Map urlsMap = liveLogLocalService.getLiveUrls(liveLog.getLiveUuid());
			String pullUrls = MapUtils.getStrValue(urlsMap, "pullUrls", "");
			String pushUrls = MapUtils.getStrValue(urlsMap, "pushUrls", "");

			//成功开播后返回的数据信息
			dataMap.put("liveUuid", liveLog.getLiveUuid());
			dataMap.put("liveUrl", liveLog.getLiveUrl());
			dataMap.put("pullUrl", liveLog.getPullUrl());
			dataMap.put("displayGraph", liveLog.getDisplayGraph());
			dataMap.put("hefanTotal", String.valueOf(user.getHefanTotal()));// 主播盒饭数
			dataMap.put("pushUrls",pushUrls);
			dataMap.put("pullUrls",pullUrls);

			// redis中维护在播的直播信息,
			LivingRoomInfoVo lriVo = new LivingRoomInfoVo();
			lriVo.setHeadImg(user.getHeadImg());// 主播头像
			lriVo.setLiveUuid(liveLog.getLiveUuid());// 直播uuid
			lriVo.setName(user.getNickName());// 主播昵称
			lriVo.setChatRoomId(findRoom.getChatRoomId());// 聊天室id
			lriVo.setLiveUrl(liveLog.getPullUrl());// 拉流地址
			lriVo.setPersonSign(liveVo.getLiveName());// 直播名
			lriVo.setId(liveVo.getUserId());// 主播id
			lriVo.setUserId(liveVo.getUserId());// 主播id
			lriVo.setType(user.getUserType());// 主播类型
			lriVo.setLiveImg(liveVo.getLiveImg());// 直播间封面
			lriVo.setDisplayGraph(liveLog.getDisplayGraph());// 点亮样式
			lriVo.setLocation(StringUtils.isNotBlank(liveLog.getLocation()) ? liveLog.getLocation():GlobalConstants.DEFAULT_LOCATION);
			lriVo.setHefanTotal(String.valueOf(user.getHefanTotal()));//主播盒饭数
			lriVo.setPullUrls(pullUrls);//拉流地址
			lriVo.setPushUrls(pushUrls);//推流地址
			lriVo.setStartLiveTime(System.currentTimeMillis());//开播时间，用于列表排序
			//新增字段VIP
			lriVo.setIsShow(1);
			lriVo.setIsVipLive(0);
			lriVo.setDoubleSrc(0);
			lriVo.setRotate(0);
			lriVo.setIsLandscape(liveVo.getIsLandscape());

			//存储live_log live_room LivingRoomInfoVo 数据缓存到 redis中
			if(!livingRedisOptService.addLiveLogData(liveRoom, liveLog, lriVo)){
				return JSON.toJSONString(new ResultPojo(ResultCode.UNSUCCESS));
			}

			return JSON.toJSONString(new ResultBean(ResultCode.SUCCESS, dataMap));
		} catch (Exception e) {
			logger.error("开启直播失败", e);
			return JSON.toJSONString(new ResultPojo(ResultCode.UnknownException));
		}
	}

	/**
	 * 开播成功后进行
	 * liveRoom liveLog
	 * 更新列表、机器人等操作
	 */
	@RequestMapping("/livePush")
	@ResponseBody
	public String livePush(HttpServletRequest req) {
		try {
			// 接参
			LiveUserOptVo vo = HttpUtils.initParam(req, LiveUserOptVo.class);
			if ( null == vo || StringUtils.isBlank(vo.getLiveUuid()) || StringUtils.isBlank(vo.getUserId()) ||
					vo.getChatRoomId() <= 0 || StringUtils.isBlank(vo.getToken())){
				return JSON.toJSONString(new ResultPojo(ResultCode.ParamException));
			}
			WebUser user = userLocalService.getWebUserByUserId(vo.getUserId());
			if ( null == user ) {
				return JSON.toJSONString(new ResultPojo(ResultCode.UserNotFound));
			}
			//验证开播token
			String token = livingRedisOptService.getLiveToken(vo.getUserId());
			if(StringUtils.isBlank(token) || !token.equals(vo.getToken())){
				return JSON.toJSONString(new ResultPojo(ResultCode.TOKEN_ERROR));
			}
			//清除开播token
			livingRedisOptService.delLiveToken(vo.getUserId());

			//redis 中取LiveLog和LiveRoom数据
			LiveLog liveLog = livingRedisOptService.getLiveLogData(vo.getUserId());
			if ( null == liveLog ) {
				return JSON.toJSONString(new ResultPojo(ResultCode.LiveIsNull));
			}
			//主播ID和liveLog 中ID不一致
			if( !liveLog.getUserId().equals(vo.getUserId())){
				return JSON.toJSONString(new ResultPojo(ResultCode.AuthError));
			}
			//chatRoomID不正确
			if (liveLog.getChatRoomId() != vo.getChatRoomId()) {
				return JSON.toJSONString(new ResultPojo(ResultCode.ParamException));
			}
			LiveRoom liveRoom = livingRedisOptService.getLiveRoomData(vo.getUserId());
			if ( null == liveRoom ){
				return JSON.toJSONString(new ResultPojo(ResultCode.LiveIsNull));
			}
			Timestamp now_ = new Timestamp(new Date().getTime());
			liveLog.setStartTime(now_);
			liveRoom.setStartTime(now_);
			//更新live_room直播状态和插入live_log直播数据，结束后清除缓存数据
			if ( !liveLogLocalService.liveStartOperate(liveRoom, liveLog)) {
				livingRedisOptService.delLiveCacheData(vo.getUserId());
				return JSON.toJSONString(new ResultPojo(ResultCode.UNSUCCESS));
			}

			//开播成功后，在redis中存入直播信息
			LivingRoomInfoVo livingRoomInfoVo = livingRedisOptService.getLivingRoomInfoVoData(vo.getUserId());
			if (null != livingRoomInfoVo) {
				livingRedisOptService.addLivingInfo_Hash(vo.getUserId(), JSON.toJSONString(livingRoomInfoVo));
			}
			if (!livingRedisOptService.isExistsLivingInfo_Hash(vo.getUserId())){
				logger.info("开播时直播间信息存入redis失败");
				return JSON.toJSONString(new ResultPojo(ResultCode.UNSUCCESS));
			}
			logger.info("开播成功接口：在redis中存入直播信息成功");

			//更新最新、热门列表页静态文件 异步
			livingLocalService.liveStartOpt();
			logger.info("开播成功接口：异步执行更新直播列表文件");
			//异步执行推送开播提醒、机器人初始化、初始化心跳数据
			liveLogLocalService.doPush(liveLog, user);

			logger.info("开播成功接口：操作结束，开播成功");
			return JSON.toJSONString(new ResultPojo(ResultCode.SUCCESS));
		}catch (Exception e){
			logger.error("开播提醒失败",e);
			return JSON.toJSONString(new ResultPojo(ResultCode.UnknownException));
		}
	}

	/**
	 * 主播关闭直播
	 */
	@ResponseBody
	@RequestMapping("/liveEnd")
	public String liveEnd(HttpServletRequest req) {
		String logId = RpcContext.getContext().getAttachment("logId");
		long start = System.currentTimeMillis();
		logger.info("logId:{}:关播开始时间:{}",logId,start);
		LiveVo liveVo = HttpUtils.initParam(req, LiveVo.class);
		try {
			// 参数异常
			if (null == liveVo || StringUtils.isBlank(liveVo.getUserId())
					|| StringUtils.isBlank(liveVo.getLiveUuid())) {
				return JSON.toJSONString(new ResultPojo(ResultCode.ParamException));
			}
			Timestamp now_ = new Timestamp(new Date().getTime());
			Map<String, Object> dataMap = new HashMap<String, Object>();
			LiveRoom liveRoom = liveRoomLocalService.getLiveRoomByUserId(liveVo.getUserId());
			long start1 = System.currentTimeMillis();
			logger.info("logId:{}:查询live_room耗时:{}毫秒",logId,start1 - start);
			// 直播已经关闭或不存在
			if (null == liveRoom || liveRoom.getStatus() == GlobalConstants.AUTHOR_LIVEEND) {
				return JSON.toJSONString(new ResultPojo(ResultCode.LiveIsClose));
			}

			WebUser user = userLocalService.getWebUserByUserId(liveVo.getUserId());
			long start2 = System.currentTimeMillis();
			logger.info("logId:{}:查询web_user耗时:{}毫秒",logId,start2 - start1);
			if (null == user) {
				return JSON.toJSONString(new ResultPojo(ResultCode.ParamException));
			}
			// 获取用户直播信息
			LiveLog liveLog_ = liveLogLocalService.getLiveLogByUuid(liveVo.getLiveUuid());
			long start3 = System.currentTimeMillis();
			logger.info("logId:{}:查询web_user耗时:{}毫秒",logId,start3 - start2);
			if (null == liveLog_) {
				return JSON.toJSONString(new ResultPojo(ResultCode.ParamException));
			}
			if (!liveLog_.getUserId().equals(liveVo.getUserId())) {
				return JSON.toJSONString(new ResultPojo(ResultCode.AuthError));
			}
			liveLog_.setEndTime(now_);
			// 闭环当次直播数据
			long num = liveLog_.getWatchNum();
			try {
					String watchNum = livingRedisOptService.getLivingWatchNum(liveLog_.getLiveUuid());
				if (StringUtils.isNotBlank(watchNum)) {
					num = Long.valueOf(watchNum);
					liveLog_.setWatchNum(num);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				String addNUm = livingRedisOptService.getAddNumForRoom(liveVo.getUserId());
				if ( null != addNUm && Long.valueOf(addNUm) >= 0) {
					num += Long.valueOf(addNUm);
					logger.info("{}加入了{}额外人数",liveVo.getUserId(),addNUm);
				}
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
			long start4 = System.currentTimeMillis();
			logger.info("logId:{}:查询redis中观看人数,额外人数耗时:{}毫秒",logId,start4 - start3);
			//更新live_room直播状态，更新live_log中结束时间人数收入等
			liveLog_ = liveLogLocalService.liveEndOperate(liveLog_);
			long start5 = System.currentTimeMillis();
			logger.info("logId:{}:执行live_log,live_room更新,redis中清除直播记录的操作耗时:{}毫秒",logId,start5 - start4);
			if (null == liveLog_) {
				return JSON.toJSONString(new ResultPojo(ResultCode.UNSUCCESS));
			}
			long ticketCount = livingRedisOptService.getTicketCountByUuid(liveVo.getLiveUuid());
			dataMap.put("ticketCount", ticketCount);
			dataMap.put("watchNum", num);
			dataMap.put("liveLength", liveLog_.getLiveLength());

			//异步处理明星自动分享动态
			if (user.getUserType() == GlobalConstants.USER_TYPE_STAR || user.getUserType() == GlobalConstants.USER_TYPE_SITE) {
				if (liveLog_.getLiveLength() > 120) { // 两分钟以上才分享
					String pre = DynamicProperties.getString("replay.domain.pre");
					String suf = DynamicProperties.getString("replay.domain.suf");
					LiveDynamicVo liveDynamicVo = new LiveDynamicVo();
					liveDynamicVo.setUserId(liveVo.getUserId());
					liveDynamicVo.setBackImg(liveLog_.getLiveImg().substring(0, 10) + "1" + liveLog_.getLiveImg().substring(10));
					liveDynamicVo.setFromType("0");// 来源
					liveDynamicVo.setIsSync(1);// 是否同步到视频
					liveDynamicVo.setLength(DateUtils.getHms(liveLog_.getLiveLength() * 1000));
					liveDynamicVo.setMessageInfo(liveLog_.getLiveName());// 动态文字
					liveDynamicVo.setPathTrans(pre + liveLog_.getLiveUuid() + suf);// 拉流地址
					liveDynamicVo.setTranscode(true);// 是否转码
					liveDynamicVo.setMessageType("3");// 3表示动态类型是视频
					liveDynamicVo.setTimes(liveLog_.getWatchNum());
					roomOptLocalService.shareLive(liveDynamicVo);
				}
			}
			//异步发送IM消息,发送三次
			liveImOptLocalService.sendImMessage(user, liveLog_.getChatRoomId(), liveVo.getLiveUuid(),String.valueOf(num),
					String.valueOf(liveLog_.getLiveLength()),String.valueOf(liveLog_.getTicketCount()));
			long start6 = System.currentTimeMillis();
			logger.info("logId:{}:异步分享动态和异步发送关播IM广播耗时:{}毫秒", logId, start6 - start5);
			logger.info("直播关闭完成");
			return JSON.toJSONString(new ResultBean(ResultCode.SUCCESS, dataMap));
		} catch (Exception e) {
			logger.error("直播关闭失败", e);
			return JSON.toJSONString(new ResultPojo(ResultCode.UnknownException));
		}
	}

	/**
	 * 获取在线用户列表
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	@RequestMapping(value = "/getOnlineUserlist", method = RequestMethod.GET)
	@ResponseBody
	public String getOnlineUserlist(HttpServletRequest request) {
		ResultBean resultBean = new ResultBean();
		// 接参
		Map paramMap = HttpUtils.initParam(request, Map.class);
		if (null == paramMap || paramMap.isEmpty()) {
			resultBean.setCode(ResultCode.ParamException.get_code());
			resultBean.setMsg(ResultCode.ParamException.getMsg());
			return JSON.toJSONString(resultBean);
		}
		String liveUuid = MapUtils.getStrValue(paramMap, "liveUuid", "");// 直播UUID
		int chatRoomId = MapUtils.getIntValue(paramMap, "chatRoomId", -1);// 进入直播间对应聊天室id
		String authoruserId = MapUtils.getStrValue(paramMap, "authoruserId", "");// 主播ID
		int pageNo = MapUtils.getIntValue(paramMap, "pageNo", -1);
		int pageSize = MapUtils.getIntValue(paramMap, "pageSize", -1);

		if (StringUtils.isBlank(liveUuid) || chatRoomId <= 0 || StringUtils.isBlank(authoruserId) || pageNo <= 0
				|| pageSize <= 0) {
			resultBean.setCode(ResultCode.ParamException.get_code());
			resultBean.setMsg(ResultCode.ParamException.getMsg());
			return JSON.toJSONString(resultBean);
		}
		
		try {
			try {
				if (null == roomEnterExitOptService.getLivingRoomInfoByAuthId(authoruserId)) {
					logger.info("未找到该直播间信息，主播id＝", authoruserId);
					resultBean.setCode(ResultCode.Live_Room_Info_Is_Err.get_code());
					resultBean.setMsg(ResultCode.Live_Room_Info_Is_Err.getMsg());
					return JSON.toJSONString(resultBean);
				}
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("该直播间信息查询--处理失败", e);
				resultBean.setCode(ResultCode.UNSUCCESS.get_code());
				resultBean.setMsg(ResultCode.UNSUCCESS.getMsg());
				return JSON.toJSONString(resultBean);
			}

			Page page = new Page();
			page.pageNo = pageNo;
			page.pageSize = pageSize;
			// 首页
			if (pageNo == 1) {
				String infoRedis = livingRedisOptService.getLivingHomePageUserListInfo(liveUuid);
				if (StringUtils.isNotBlank(infoRedis)) {
					List resutList = JSON.parseObject(infoRedis, List.class);
					if (null != resutList && resutList.size() == 20) {
						page.setResult(resutList);
						resultBean.setData(page);
						resultBean.setCode(ResultCode.SUCCESS.get_code());
						resultBean.setMsg(ResultCode.SUCCESS.getMsg());
						return JSON.toJSONString(resultBean);
					}
				}
			}

			page = livingLocalService.getOnlineUserlist(authoruserId, page);
			if (pageNo == 1) {
				livingRedisOptService.initLivingHomePageUserListInfo(liveUuid, JSON.toJSONString(page.getResult()));
			}
			resultBean.setData(page);
			resultBean.setCode(ResultCode.SUCCESS.get_code());
			resultBean.setMsg(ResultCode.SUCCESS.getMsg());
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("获取直播间在线用户列表", e);
			resultBean.setCode(ResultCode.UNSUCCESS.get_code());
			resultBean.setMsg(ResultCode.UNSUCCESS.getMsg());
			return JSON.toJSONString(resultBean);
		}
		return JSON.toJSONString(resultBean);
	}

	/**
	 * 用户进入直播间
	 */
	@SuppressWarnings({ "rawtypes" })
	@RequestMapping(value = "/joinLiveRoom", method = RequestMethod.GET)
	@ResponseBody
	public String joinLiveRoom(HttpServletRequest request) {
		ResultBean resultBean = new ResultBean();
		// 接参
		Map paramMap = HttpUtils.initParam(request, Map.class);
		if (null == paramMap || paramMap.isEmpty()) {
			resultBean.setCode(ResultCode.ParamException.get_code());
			resultBean.setMsg(ResultCode.ParamException.getMsg());
			return JSON.toJSONString(resultBean);
		}
		String userId = MapUtils.getStrValue(paramMap, "userId", "");// 进入直播间用户id
		String nickName = MapUtils.getStrValue(paramMap, "nickName", "");// 进入直播间用户昵称
		String headImg = MapUtils.getStrValue(paramMap, "headImg", "");// 进入直播间用户头像
		int userLevel = MapUtils.getIntValue(paramMap, "userLevel", -1);// 进入直播间用户等级
		int userType = MapUtils.getIntValue(paramMap, "userType", -1);// 进入直播间用户类型
		String authoruserId = MapUtils.getStrValue(paramMap, "authoruserId", "");// 主播id
		int chatRoomId = MapUtils.getIntValue(paramMap, "chatRoomId", -1);// 进入直播间对应聊天室id
		String liveUuid = MapUtils.getStrValue(paramMap, "liveUuid", "");// 直播间UUID
		String deviceToken = MapUtils.getStrValue(paramMap, "deviceToken", "");// 设备token

		if (StringUtils.isBlank(userId) || StringUtils.isBlank(nickName) || chatRoomId < 0 || userType < 0
				|| StringUtils.isBlank(headImg) || userLevel < 0 || StringUtils.isBlank(liveUuid)
				|| StringUtils.isBlank(authoruserId)) {
			resultBean.setCode(ResultCode.ParamException.get_code());
			resultBean.setMsg(ResultCode.ParamException.getMsg());
			return JSON.toJSONString(resultBean);
		}

		try {
			LivingRoomInfoVo livingRoomInfoVo = roomEnterExitOptService.getLivingRoomInfoByAuthId(authoruserId);
			if (null == livingRoomInfoVo) {
				logger.info("进入直播间不存在authoruserId" + authoruserId);
				resultBean.setCode(ResultCode.LiveIsNull.get_code());
				resultBean.setMsg(ResultCode.LiveIsNull.getMsg());
				return JSON.toJSONString(resultBean);
			}
			if (!livingRoomInfoVo.getLiveUuid().equals(liveUuid)) {
				logger.info("进入直播间LiveUuid不一致：liveUuid=" + liveUuid + "  Living_liveUuid=" + livingRoomInfoVo.getLiveUuid());
				resultBean.setCode(ResultCode.LiveIsNull.get_code());
				resultBean.setMsg(ResultCode.LiveIsNull.getMsg());
				return JSON.toJSONString(resultBean);
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("进入直播间LiveUuid不一致：操作失败", e);
		}

		try {
			if (userId.equals(authoruserId)) {
				logger.info("用户不能进入自己的直播间");
				resultBean.setCode(ResultCode.ResultCode_4079.get_code());
				resultBean.setMsg(ResultCode.ResultCode_4079.getMsg());
				return JSON.toJSONString(resultBean);
			}

			try {
				if (StringUtils.isNotBlank(livingRedisOptService.getLivingForbiddenEnter(liveUuid, userId))) {
					logger.info("该用户已被该直播间踢出");
					resultBean.setCode(ResultCode.userIsOut.get_code());
					resultBean.setMsg(ResultCode.userIsOut.getMsg());
					return JSON.toJSONString(resultBean);
				}
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("判断该用户是否被踢出--处理失败", e);
				resultBean.setCode(ResultCode.UNSUCCESS.get_code());
				resultBean.setMsg(ResultCode.UNSUCCESS.getMsg());
				return JSON.toJSONString(resultBean);
			}

			try {
				if (null != roomEnterExitOptService.getLivingRoomInfoByAuthId(userId)) {
					logger.info("该用户正在直播中");
					resultBean.setCode(ResultCode.LiveIsLiveing.get_code());
					resultBean.setMsg(ResultCode.LiveIsLiveing.getMsg());
					return JSON.toJSONString(resultBean);
				}
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("判断该用户是否在直播中--处理失败", e);
				resultBean.setCode(ResultCode.UNSUCCESS.get_code());
				resultBean.setMsg(ResultCode.UNSUCCESS.getMsg());
				return JSON.toJSONString(resultBean);
			}

//			try {
//				/**
//				 * 用户进入直播间阀值处理
//				 */
//				LivingVo item = new LivingVo();
//				item.setAuthoruserId(authoruserId);
//				item.setChatRoomId(chatRoomId);
//				item.setLiveUuid(liveUuid);
//				item.setUserId(userId);
//				item.setUserType(userType);
//				item.setNickName(nickName);
//				item.setHeadImg(headImg);
//				item.setUserLevel(userLevel);
//				ResultBean isEnterQueue = livingLocalService.enterQueue(item);
//				if (null != isEnterQueue && isEnterQueue.getCode() !=
//						ResultCode.SUCCESS.get_code()) {
//					return JSON.toJSONString(isEnterQueue);
//				}
//			} catch (Exception ex) {
//				ex.printStackTrace();
//				logger.info("用户排队操作失败！");
//			}

			ResultBean enterLiveRoomCheck = livingLocalService.enterLiveRoomCheck(userId, chatRoomId, liveUuid, authoruserId,
					deviceToken);
			if (enterLiveRoomCheck.getCode() != ResultCode.SUCCESS.get_code()) {
				logger.info("用户有未退出的直播间观看记录");
				return JSON.toJSONString(enterLiveRoomCheck);
			}
;
			LiveRoomPersonVo livePerson = new LiveRoomPersonVo();
			livePerson.setUserId(userId);
			livePerson.setUserType(userType);
			livePerson.setHeadImg(headImg);
			livePerson.setUserLevel(userLevel);
			livePerson.setNickName(nickName);
			livingLocalService.enterLiveRoomOperate(livePerson, liveUuid, chatRoomId,authoruserId, deviceToken);

			long watchNuminRdeis = 0;
			try {
				// 更新直播间实际观看人次
				watchNuminRdeis = livingRedisOptService.addLivingWatchNum(liveUuid, 1);
				if (watchNuminRdeis > 0 && watchNuminRdeis % 100 == 0) {
					liveLogLocalService.changeWatchNum(liveUuid, chatRoomId, 100);
				}
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("直播间人数/人次更新--处理失败");
			}
			logger.info("用户进入直播间成功！");

			// 加入机器人异步处理
			livingLocalService.addRobotWhenJoin(liveUuid, chatRoomId, authoruserId);

			resultBean.setCode(ResultCode.SUCCESS.get_code());
			resultBean.setMsg(ResultCode.SUCCESS.getMsg());
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("用户进入直播间失败", e);
			resultBean.setCode(ResultCode.UNSUCCESS.get_code());
			resultBean.setMsg(ResultCode.UNSUCCESS.getMsg());
			return JSON.toJSONString(resultBean);
		}
		return JSON.toJSONString(resultBean);
	}

	/**
	 * 用户离开直播间
	 */
	@SuppressWarnings({ "rawtypes" })
	@RequestMapping(value = "/leftLiveRoom", method = RequestMethod.GET)
	@ResponseBody
	public String leftLiveRoom(HttpServletRequest request) {
		ResultBean resultBean = new ResultBean();
		// 接参
		Map paramMap = HttpUtils.initParam(request, Map.class);
		if (null == paramMap || paramMap.isEmpty()) {
			resultBean.setCode(ResultCode.ParamException.get_code());
			resultBean.setMsg(ResultCode.ParamException.getMsg());
			return JSON.toJSONString(resultBean);
		}
		String liveUuid = MapUtils.getStrValue(paramMap, "liveUuid", "");// 直播间UUID
		int chatRoomId = MapUtils.getIntValue(paramMap, "chatRoomId", -1);// 进入直播间对应聊天室id
		String authoruserId = MapUtils.getStrValue(paramMap, "authoruserId", "");// 主播id
		String userId = MapUtils.getStrValue(paramMap, "userId", "");// 进入直播间用户id

		if (StringUtils.isBlank(userId) || chatRoomId < 0 || StringUtils.isBlank(liveUuid)
				|| StringUtils.isBlank(authoruserId)) {
			resultBean.setCode(ResultCode.ParamException.get_code());
			resultBean.setMsg(ResultCode.ParamException.getMsg());
			return JSON.toJSONString(resultBean);
		}

		try {
			livingLocalService.exitLiveRoomOperate(userId, chatRoomId, liveUuid, authoruserId);
			logger.info("用户离开直播间成功！");
			// 移除机器人异步处理
			livingLocalService.removeRobotWhenLeft(chatRoomId, liveUuid, authoruserId);

			resultBean.setCode(ResultCode.SUCCESS.get_code());
			resultBean.setMsg(ResultCode.SUCCESS.getMsg());
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("用户离开直播间失败", e);
			resultBean.setCode(ResultCode.UNSUCCESS.get_code());
			resultBean.setMsg(ResultCode.UNSUCCESS.getMsg());
			return JSON.toJSONString(resultBean);
		}
		return JSON.toJSONString(resultBean);
	}

	/**
	 * 直播预告
	 * 
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value = "/liveNotice", method = RequestMethod.GET)
	public String liveNotice() {
		ResultBean resultBean = new ResultBean();
		try {
			resultBean.setData(liveNoticeLocalService.liveNotice());
			resultBean.setCode(ResultCode.SUCCESS.get_code());
			resultBean.setMsg(ResultCode.SUCCESS.getMsg());
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("直播预告获取失败", e);
			resultBean.setCode(ResultCode.UNSUCCESS.get_code());
			resultBean.setMsg(ResultCode.UNSUCCESS.getMsg());
		}
		return JSON.toJSONString(resultBean);
	}

	/**
	 * 提交用户观看时长
	 */
	@SuppressWarnings({ "rawtypes" })
	@RequestMapping(value = "/submitUserWatchTime", method = RequestMethod.GET)
	@ResponseBody
	public String submitUserWatchTime(HttpServletRequest request) {
		ResultBean resultBean = new ResultBean();
		// 接参
		Map paramMap = HttpUtils.initParam(request, Map.class);
		if (null == paramMap || paramMap.isEmpty()) {
			resultBean.setCode(ResultCode.ParamException.get_code());
			resultBean.setMsg(ResultCode.ParamException.getMsg());
			return JSON.toJSONString(resultBean);
		}
		String userId = MapUtils.getStrValue(paramMap, "userId", "");// 用户id
		long watchTime = MapUtils.getLongValue(paramMap, "watchTime", 0);// 观看时长

		if (StringUtils.isBlank(userId) || watchTime <= 0) {
			resultBean.setCode(ResultCode.ParamException.get_code());
			resultBean.setMsg(ResultCode.ParamException.getMsg());
			return JSON.toJSONString(resultBean);
		}
		try {
			/**
			 * 更新观看用户列表,向云信端发送群自定义消息
			 */
			Message message = new Message();
			message.put("liveUserExperience", JSON.toJSONString(paramMap));
			message.setTopic(TopicRegistry.HEFAN_LIVE_USER_EXPERIENCE);
			String onsEnv = DynamicProperties.getString("ons.env");
			message.setTag(onsEnv);
			onsProducer.sendMsg(message);

			resultBean.setCode(ResultCode.SUCCESS.get_code());
			resultBean.setMsg(ResultCode.SUCCESS.getMsg());
			return JSON.toJSONString(resultBean);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("用户更新观看时长失败", e);
			resultBean.setCode(ResultCode.UNSUCCESS.get_code());
			resultBean.setMsg(ResultCode.UNSUCCESS.getMsg());
			return JSON.toJSONString(resultBean);
		}
	}

	/**
	 * 获取直播间盒饭数和人数-直播中
	 */
	@RequestMapping(value = "/getLiveInfo", method = RequestMethod.GET)
	@ResponseBody
	public String getLiveInfo(HttpServletRequest req) {
		try {
			LiveVo liveVo = HttpUtils.initParam(req, LiveVo.class);
			if (null == liveVo || StringUtils.isBlank(liveVo.getLiveUuid())) {
				return JSON.toJSONString(new ResultPojo(ResultCode.ParamException));
			}
			WebUser user = null;
			//新版本增加参数userId 2016.12.28
			if (StringUtils.isNotBlank(liveVo.getUserId())){
				user = userLocalService.findUserInfoFromCache(liveVo.getUserId());
			}else {
				LiveLog liveLog = liveLogLocalService.getLiveLogByUuid(liveVo.getLiveUuid());
				if (null == liveLog) {
					return JSON.toJSONString(new ResultPojo(ResultCode.LiveIsNull));
				}
				liveVo.setUserId(liveLog.getUserId());
				user = userLocalService.getWebUserByUserId(liveLog.getUserId());
			}
			if (null == user) {
				return JSON.toJSONString(new ResultPojo(ResultCode.UserNotFound));
			}
			long watchNum = livingLocalService.getLiveRoomPeoleCount(user.getUserId());
			try {
				String addNUm = livingRedisOptService.getAddNumForRoom(liveVo.getUserId());
				if ( null != addNUm && Long.valueOf(addNUm) >= 0) {
					watchNum += Long.valueOf(addNUm);
					logger.info("{}加入了{}额外人数",liveVo.getUserId(),addNUm);
				}
			} catch (NumberFormatException e) {
				e.printStackTrace();
			}
			Map mapParam = new HashMap();
			mapParam.put("hefanTotal", user.getHefanTotal());
			mapParam.put("watchNum",watchNum);
			return JSON.toJSONString(new ResultBean(ResultCode.SUCCESS, mapParam));
		} catch (Exception e) {
			return JSON.toJSONString(new ResultPojo(ResultCode.UnknownException));
		}
	}

	/**
	 * 获取直播观看人次和盒饭数--结束后
	 */
	@RequestMapping("/findLiveLogInfo")
	@ResponseBody
	public String findLiveLogInfo(HttpServletRequest request) {
		try {
			LiveVo vo = HttpUtils.initParam(request, LiveVo.class);
			if (null == vo || StringUtils.isBlank(vo.getLiveUuid())) {
				return JSON.toJSONString(new ResultPojo(ResultCode.ParamException));
			}
			LiveLog liveLog = liveLogLocalService.getLiveLogByUuid(vo.getLiveUuid());
			if (liveLog == null) {
				return JSON.toJSONString(new ResultPojo(ResultCode.LiveIsNull));
			} else {
				long ticketCount = liveLog.getTicketCount();
				if (ticketCount == 0) {
					ticketCount = livingRedisOptService.getTicketCountByUuid(vo.getLiveUuid());
				}
				long watchNum = liveLog.getWatchNum();
				String watchStr = livingRedisOptService.getLivingWatchNum(liveLog.getLiveUuid());
				if(StringUtils.isNotBlank(watchStr)){
					watchNum = Long.valueOf(watchStr);
				}
				try {
					String addNUm = livingRedisOptService.getAddNumForRoom(liveLog.getUserId());
					if ( null != addNUm && Long.valueOf(addNUm) >= 0) {
						watchNum += Long.valueOf(addNUm);
						logger.info("{}加入了{}额外人数",liveLog.getUserId(),addNUm);
					}
				} catch (NumberFormatException e) {
					e.printStackTrace();
				}
				long liveLength = liveLog.getLiveLength();
				if ( null == liveLog.getEndTime() || liveLength == 0){
					liveLength = (System.currentTimeMillis() - liveLog.getStartTime().getTime())/1000;
				}
				Map<String, Object> dataMap = new HashMap<>();
				dataMap.put("ticketCount", ticketCount);
				dataMap.put("watchNum", watchNum);
				dataMap.put("liveLength", liveLength);
				return JSON.toJSONString(new ResultBean(ResultCode.SUCCESS, dataMap));
			}
		} catch (Exception e) {
			logger.error("查询直播结束统计信息失败", e);
			return JSON.toJSONString(new ResultPojo(ResultCode.UnknownException));
		}
	}
}
